在昨天有簡單提到了一下 logging 這個工具,今天會再做更深入的介紹,因為當使用者在使用我們的套件的時候,提供好的訊息也可以讓他們更快更容易的操作,我們在開發的時候有時候也能透過這些額外的資訊更好除錯。今天的文章也會參考官方的文件進行介紹。
要使用 logging,因為是 Python 內建的功能,所以可以直接 import 後就能使用。昨天我們是直接使用 basicConfig 進行 logging 的設定:
import logging
logging.basicConfig(level=logging.DEBUG)
這段程式碼的意思就是,把顯示 logging 的 level 改成 DEBUG,他總共會有五種 level,分別為:
DEBUG:提供詳細的說明,通常會先隱藏,讓有需要的人再來查看,用來診斷跟分析問題會使用。INFO:用來確認事件是否完成,或是程式是否如預期中運行會使用,提供一些簡單的資訊確認。WARNING:回報未來可能會造成問題的警告,或是提醒非預期的事情發生。ERROR:回報程式發生什麼錯誤,可能造成哪些功能無法使用。CRITICAL:回報更嚴重的錯誤產生,可能造成整個程式無法運作。他們的顯示優先度也照著上面的排列,假設 level 設成 DEBUG 會全部都顯示,如果是設成 ERROR,那就只會顯示 ERROR 跟 CRITICAL。
熟悉這五個類別,就可以判斷出我們在提供說明資訊的時候,應該套用哪個 level,或是在看別人的 logging 的時候,能判斷出訊息中的類別,更快能找到需要優先閱讀的項目。
通常預設顯示都是到 WARNING,當我們想要看更多詳細資訊的時候才會把 level 調整成 DEBUG。上面那段程式碼就是把預設進行修改,所以我們才能看到 requests 套件提供的更多訊息。
如果是直接使用 basicConfig 的話,他會直接一次影響到所有的 logging 顯示,但我們可能會想讓不同的 function,顯示不同的 level。譬如說我平常使用的時候,不會特別想知道 DEBUG 裡的訊息,想要再發生問題的時候,進行除錯時再打開。這時候就可以使用 logger 進行 level 的調整。
logger 的概念就很像他是一個獨立出來的 config,可以進行設定的調整,但不影響到其他 logger。要產生他也很簡單,只要使用 logging 的 getLogger 就好,程式碼如下:
import logging
# 這行還是要,有點像是初始化的感覺
logging.basicConfig()
logger = logging.getLogger()
這樣我們就會獲得一個 logger,之後我們就能使用 logger.setLevel() 來改變顯示的優先度,也可以開始使用像是 logger.info() 來提供我們自製的訊息:
logger.setLevel(logging.INFO)
logger.debug("Test 1")
logger.info("Test 2")
logger.error("Test 3")
上面的程式碼代表我們先把優先度設成 INFO,然後下面會是我們的自製說明。由於我們現在的優先度是 INFO,所以 Test 1 這個訊息不會顯示,其他則會顯示像是:
可以看到 logger 會根據我們使用的 level 來顯示訊息,中間那個 root 是指 logger 的名稱,因為我們在 getLogger 的時候沒傳入字串進去,所以會是預設的 root。我們可以傳入自己想要的命名,或是使用 getLogger(__name__) 來讓名稱變成當前 logger 所在的模組名稱。
這個顯示的格式,其實也可以透過 basicConfig 去定義,只要更新 format 參數就可以,可以參考文章裡的:Changing the format of displayed messages
有了 logger 後,我們可以在我們的 function 裡多加一個 debug 參數,如果他是 True,我們就能把優先度改變成 DEBUG,這樣我們可以讓使用者手動決定要不要顯示更詳細的訊息,一樣是使用到 setLogger,程式碼可以寫成這樣:
import logging
logging.basicConfig()
logger = logging.getLogger()
def statcast_search(**params, debug = False):
if (debug):
logger.setLogger(logging.DEBUG)
# other code...
透過一個簡單的判斷式去處理,然後預設 debug 為 False。之後我們就可以使用 logger.debug 來存放一些除錯用的詳細訊息,像是輸入的 params 長得如何,或是組合完給 requests 的 URL,或是一些當前的設定,都可以使用。
今天再更深入介紹 logging 這個內建功能,如果使用好的話,能讓不管使用者或開發者,都能獲得更詳細分好類的資訊,是個在開發 Python 套件時的實用工具,是個比直接使用 print 來除錯外更好的選擇。另外他在 Python 當 API Server 的時候也是一個很好用的工具,可以透過 level 快速找到問題,大家可以多熟悉這個工具。
最後一樣感謝大家耐心地看到這,這已經是倒數第二天的文章,真的很感謝,有任何的問題與建議一樣歡迎大家在留言告訴我,明天會做個這次鐵人賽的總整理,明天見,掰掰。